#ifndef _SORTKEY_H_
#define _SORTKEY_H_

#include <common.h>

/*
** {======================================================
** SortKey
** =======================================================
*/

#define SORTKEY_BITS 64
#define SORTKEY_RESERVED_BITS 1
#define SORTKEY_VIEWID_BITS BCFX_CONFIG_VIEW_ID_BITS
#define SORTKEY_NOTTOUCH_BITS 1
#define SORTKEY_ISDRAW_BITS 1
#define SORTKEY_SORTTYPE_BITS 2
#define SORTKEY_BLEND_BITS 2
#define SORTKEY_PROGRAM_BITS BCFX_CONFIG_PROGRAM_BITS
#define SORTKEY_DEPTH_BITS 24
#define SORTKEY_SEQUENCE_BITS 16

#define SORTKEY_VIEWID_SHIFT (SORTKEY_BITS - SORTKEY_RESERVED_BITS - SORTKEY_VIEWID_BITS)
#define SORTKEY_NOTTOUCH_SHIFT (SORTKEY_VIEWID_SHIFT - SORTKEY_NOTTOUCH_BITS)
#define SORTKEY_ISDRAW_SHIFT (SORTKEY_NOTTOUCH_SHIFT - SORTKEY_ISDRAW_BITS)

#define SORTKEY_SORTTYPE_SHIFT (SORTKEY_ISDRAW_SHIFT - SORTKEY_SORTTYPE_BITS)

#define SORTKEY_BLEND_SHIFT0 (SORTKEY_SORTTYPE_SHIFT - SORTKEY_BLEND_BITS)
#define SORTKEY_PROGRAM_SHIFT0 (SORTKEY_BLEND_SHIFT0 - SORTKEY_PROGRAM_BITS)
#define SORTKEY_DEPTH_SHIFT0 (SORTKEY_PROGRAM_SHIFT0 - SORTKEY_DEPTH_BITS)
#define SORTKEY_SEQUENCE_SHIFT0 (SORTKEY_DEPTH_SHIFT0 - SORTKEY_SEQUENCE_BITS)

#define SORTKEY_DEPTH_SHIFT1 (SORTKEY_SORTTYPE_SHIFT - SORTKEY_DEPTH_BITS)
#define SORTKEY_BLEND_SHIFT1 (SORTKEY_DEPTH_SHIFT1 - SORTKEY_BLEND_BITS)
#define SORTKEY_PROGRAM_SHIFT1 (SORTKEY_BLEND_SHIFT1 - SORTKEY_PROGRAM_BITS)
#define SORTKEY_SEQUENCE_SHIFT1 (SORTKEY_PROGRAM_SHIFT1 - SORTKEY_SEQUENCE_BITS)

#define SORTKEY_SEQUENCE_SHIFT2 (SORTKEY_SORTTYPE_SHIFT - SORTKEY_SEQUENCE_BITS)
#define SORTKEY_BLEND_SHIFT2 (SORTKEY_SEQUENCE_SHIFT2 - SORTKEY_BLEND_BITS)
#define SORTKEY_PROGRAM_SHIFT2 (SORTKEY_BLEND_SHIFT2 - SORTKEY_PROGRAM_BITS)

#define SORTKEY_COMPUTE_SEQUENCE_SHIFT (SORTKEY_ISDRAW_SHIFT - SORTKEY_SEQUENCE_BITS)
#define SORTKEY_COMPUTE_PROGRAM_SHIFT (SORTKEY_COMPUTE_SEQUENCE_SHIFT - SORTKEY_PROGRAM_BITS)

#define SORTKEY_DEPTH_MAX BIT_MASK(SORTKEY_DEPTH_BITS)

typedef enum {
  ST_Program,
  ST_Depth,
  ST_Sequence,
} SortType;

typedef struct {
  uint8_t viewId;
  uint8_t notTouch : 1;
  uint8_t isDraw : 1;
  uint8_t sortType : 2;
  uint8_t blend : 2;
  uint16_t program : 9;
  uint32_t depth : 24;
  uint16_t sequence;
} SortKey;

uint64_t sortkey_encode(SortKey* key);
void sortkey_decode(SortKey* key, uint64_t value);

void sortUint64Array(uint64_t* values, uint32_t num);

/* }====================================================== */

#endif /* _SORTKEY_H_ */
